package com.anjiplus.template.gaea.business.modules.inf.app.service.impl;


import com.anji.plus.gaea.bean.KeyValue;
import com.anji.plus.gaea.constant.BaseOperationEnum;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anji.plus.gaea.exception.BusinessException;
import com.anji.plus.gaea.inf.exception.InfException;
import com.anji.plus.gaea.utils.GaeaAssert;
import com.anjiplus.template.gaea.business.modules.inf.app.controller.dto.InfAppDTO;
import com.anjiplus.template.gaea.business.modules.inf.app.dao.InfAppMapper;
import com.anjiplus.template.gaea.business.modules.inf.app.dao.entity.InfAppEntity;
import com.anjiplus.template.gaea.business.modules.inf.app.service.InfAppService;
import com.anjiplus.template.gaea.business.modules.inf.constant.InfAppStatusEnum;
import com.anjiplus.template.gaea.business.modules.inf.constant.InfCacheKey;
import com.anjiplus.template.gaea.business.modules.inf.constant.InfResCode;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * (InfApp)表服务实现类
 *
 * @author ultrajiaming
 * @since 2021-03-18 23:27:44
 */
@Service
public class InfAppServiceImpl implements InfAppService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private InfAppMapper infAppMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public GaeaBaseMapper<InfAppEntity> getMapper() {
        return infAppMapper;
    }

    @Override
    public void processBeforeOperation(InfAppEntity entity, BaseOperationEnum operationEnum) throws BusinessException {
        switch (operationEnum) {
            case INSERT:
                if (entity != null) {
                    entity.setAppSecret(UUID.randomUUID().toString().replaceAll("-",""));
                }
                break;
        }
    }


    @Override
    public void processAfterOperation(InfAppEntity entity, BaseOperationEnum operationEnum) throws BusinessException {
        switch (operationEnum) {
            case INSERT:
                // 缓存
                if (entity != null) {
                    String redisKey = InfCacheKey.APP_SECRET + entity.getAppId();
                    ValueOperations<String, String> valueOps = stringRedisTemplate.opsForValue();
                    valueOps.set(redisKey, entity.getAppSecret());
                }
                break;
            case UPDATE:
                if (entity != null) {
                    // 缓存
                    String redisKey = InfCacheKey.APP_SECRET + entity.getAppId();
                    ValueOperations<String, String> valueOps = stringRedisTemplate.opsForValue();
                    valueOps.set(redisKey, entity.getAppSecret());
                    if (InfAppStatusEnum.UNUSEFUL.getValue() == entity.getStatus()) {
                        stringRedisTemplate.delete(redisKey);
                    }
                }
                break;
            case DELETE:
                if (entity != null) {
                    // 删除缓存
                    String redisKey = InfCacheKey.APP_SECRET + entity.getAppId();
                    stringRedisTemplate.delete(redisKey);
                }
                break;
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSecret(Long id) {
        logger.info("{}更新秘钥服务开始，参数：{}", this.getClass().getSimpleName(), id);
        GaeaAssert.notNull(id, InfResCode.ID_NOT_NULL);
        InfAppEntity appEntity = this.getById(id);
        GaeaAssert.notNull(appEntity, InfResCode.APP_NOT_EXIST);
        appEntity.setAppSecret(UUID.randomUUID().toString().replaceAll("-",""));
        infAppMapper.updateById(appEntity);
        // 更新缓存
        String redisKey = InfCacheKey.APP_SECRET + appEntity.getAppId();
        ValueOperations<String, String> valueOps = stringRedisTemplate.opsForValue();
        valueOps.set(redisKey, appEntity.getAppSecret());
        logger.info("{}更新秘钥服务结束，更新后的秘钥：{}", this.getClass().getSimpleName(), appEntity.getAppSecret());
    }

    @Override
    public List<KeyValue> dropDown() {
        LambdaUpdateWrapper<InfAppEntity> wrapper = Wrappers.<InfAppEntity>lambdaUpdate()
                .eq(InfAppEntity::getStatus, InfAppStatusEnum.USEFUL.getValue());
        List<InfAppEntity> appEntityList = this.list(wrapper);
        List<KeyValue> keyValues = appEntityList.stream().map(app -> {
            KeyValue keyValue = new KeyValue();
            keyValue.setId(app.getAppId());
            keyValue.setText(app.getAppName());
            return keyValue;
        }).collect(Collectors.toList());
        return keyValues;
    }

    @Override
    public InfAppDTO selectByAppId(String appId) {
        if (StringUtils.isBlank(appId)) {
            return null;
        }
        InfAppEntity infApp = infAppMapper.selectOne(Wrappers.<InfAppEntity>lambdaQuery().eq(InfAppEntity::getAppId, appId));
        if (infApp == null) {
            return null;
        }
        if (InfAppStatusEnum.UNUSEFUL.getValue() == infApp.getStatus()) {
            throw InfException.code(InfResCode.APP_UNUSEFUL_ERROR);
        }
        InfAppDTO infAppDTO = new InfAppDTO();
        BeanUtils.copyProperties(infApp, infAppDTO);
        return infAppDTO;
    }

}
